// pages/songDetail/songDetail.js
import PubSub from 'pubsub-js';
import moment from 'moment'
import request from '../../utils/request';
import downloadFile from '../../utils/downloadFile'
import colorThief from "miniapp-color-thief";

// 获取全局实例
const appInstance = getApp();
let progressControlWidth = "" // 进度条总宽度
let currentWidth = "" // 进度条歌曲播放进度
let currentTimeS = "" // 计算当前拖动后的时间【s】
let IsProgressControl = false; // 是否触摸控制了进度条
let bgcDownLoadFlag = false; // 销毁组件后，不需要再下载图片

Page({
  /**
   * 页面的初始数据
   */
  data: {
    // 导航栏
    navBarHeight: 0, // 导航栏高度
    menuMarginTop: 0, // 胶囊距与头部距离
    menuHeight: 0, // 胶囊高度
    menuWidth: 0, // 胶囊宽度+右边距
    source: "", // 从那里进来的

    songContentHeaderHeight: "", // 光盘区的高度
    palette: [], // 背景颜色

    isPlay: false,// 音乐是否播放
    isTitleAnimation: false, // 标题是否滚动
    song: {}, // 歌曲详情对象
    musicId: '', // 音乐id
    musicLink: '', // 音乐的链接
    currentTime: '00:00',  // 实时时间
    durationTime: '00:00', // 总时长
    currentWidth: 0, // 实时进度条的宽度
    playOrder: 0, // 0顺序，1随机，2单曲
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.setData({
      musicId: options.musicId,
      source: options.source,
      playOrder: appInstance.globalData.musicPlayOrder // 初始化播放顺序
    })
    // 自适应胶囊区
    this.calcNavBarInfo()
    // 获取音乐详情信息【false下载图片，改变背景颜色】
    this.getMusicInfo(options.musicId, false);
    // 比较两个元素宽度，计算歌名是否滚动
    this.widthCompare()
    // 创建背景音频实例，方法等
    this.creatbackgroundAudioManager()

    // 开始图片下载分析
    bgcDownLoadFlag = true;

    if (appInstance.globalData.isMusicPlay) {
      // 正在播放，先把播放状态设置上，比如播放按钮
      this.setData({ isPlay: true })
      if (appInstance.globalData.musicId != options.musicId) {
        // 不是一首歌，去加载
        this.musicControl(true, options.musicId)
      }
    } else {
      // 没有播放，去加载播放
      this.musicControl(true, options.musicId)
    }
  },

  // 创建控制音乐播放的实例
  creatbackgroundAudioManager() {
    this.backgroundAudioManager = wx.getBackgroundAudioManager();
    // 监视音乐播放 / 暂停 / 停止
    this.backgroundAudioManager.onPlay(() => {
      this.changePlayState(true);
      // 修改全局音乐播放的状态
      appInstance.globalData.musicId = this.data.musicId;
    });
    this.backgroundAudioManager.onPause(() => {
      this.changePlayState(false);
    });
    this.backgroundAudioManager.onStop(() => {
      this.changePlayState(false);
    });

    this.backgroundAudioManager.onSeeking(() => {
      this.backgroundAudioManager.pause();
    })
    this.backgroundAudioManager.onSeeked(() => {
      this.backgroundAudioManager.play();
    })

    // 监听音乐播放自然结束【注意：时间和宽度 在onTimeUpdate已经实时计算了】
    this.backgroundAudioManager.onEnded(() => {
      // 关闭当前播放的音乐
      this.backgroundAudioManager.stop();

      if (this.data.playOrder == 2) {
        // 单曲循环【有音乐链接，不需要请求】
        this.musicControl(true, this.data.musicId, this.data.musicLink)
      } else {
        // 自动切换至下一首音乐，并且自动播放
        let publishdata = { type: 'next', playOrder: this.data.playOrder }
        this.getPubSubMusic(publishdata);
      }
    });

    // 监听音乐实时播放的进度
    this.backgroundAudioManager.onTimeUpdate(() => {
      // 正在操控进度条，就直接返回
      if (IsProgressControl) return;

      // 格式化实时的播放时间【*1000 转化为ms】
      let currentTime = moment(this.backgroundAudioManager.currentTime * 1000).format('mm:ss')

      // 实时的时长/总时长 * 进度条宽度
      let currentWidth = this.backgroundAudioManager.currentTime / (this.data.song.dt / 1000) * progressControlWidth;
      this.setData({ currentWidth, currentTime })
    })
  },

  // 修改播放状态的功能函数
  changePlayState(isPlay) {
    // 修改音乐是否的状态
    this.setData({ isPlay })

    // 修改全局音乐播放的状态
    appInstance.globalData.isMusicPlay = isPlay;
  },

  // 获取音乐详情的功能函数
  async getMusicInfo(musicId, flag) {
    let songData = await request('/song/detail', { ids: musicId });
    
    songData.songs[0]["aralosongName"] = songData.songs[0].ar.map(arName => arName.name).join('/')

    // songData.songs[0].dt 单位ms
    let durationTime = moment(songData.songs[0].dt).format('mm:ss');

    this.setData({
      song: songData.songs[0],
      durationTime
    })
    this.bgcDownload(flag)
  },

  // 点击播放/暂停的回调
  handleMusicPlay() {
    let isPlay = !this.data.isPlay;

    let { musicId, musicLink } = this.data;
    this.musicControl(isPlay, musicId, musicLink);
  },

  // 控制音乐播放/暂停的功能函数
  async musicControl(isPlay, musicId, musicLink) {
    if (isPlay) {
      // 音乐播放
      // 获取音乐播放链接
      if (!musicLink) {
        console.log('没有音乐链接，去获取');
        // 获取音乐播放链接
        let musicLinkData = await request('/song/url', { id: musicId });
        console.log(musicLinkData)
        musicLink = musicLinkData.data[0].url;
        if (!musicLink) {
          wx.showToast({
            title: '当前歌曲没有音源，自动切换下一首歌曲',
            icon: 'none'
          })
          // 如果歌曲没有音源【没有url】，则播放下一首
          this.getPubSubMusic({ type: 'next', playOrder: this.data.playOrder });
          return;
        }
        this.setData({ musicLink })
      }

      this.backgroundAudioManager.title = this.data.song.name;
      this.backgroundAudioManager.singer = this.data.song.aralosongName
      this.backgroundAudioManager.src = this.data.musicLink;
      setTimeout(() => {
        // vip歌曲
        if (this.data.song.fee == 1) {
          wx.showToast({
            title: `当前vip歌曲只可播放 ${Math.floor(this.backgroundAudioManager.duration)}s`,
            icon: 'none',
            duration: 5000
          })
        }
      }, 1000)
    } else {
      // 暂停音乐
      this.backgroundAudioManager.pause();
    }
  },

  // 计算进度条和跳转时间的函数
  handleProgresCalc(e) {
    // 计算当前宽度
    currentWidth = (e.touches[0].clientX - e.currentTarget.offsetLeft)
    if (currentWidth >= progressControlWidth) currentWidth = progressControlWidth;
    else if (currentWidth <= 0) currentWidth = 0

    // 计算时间 ，单位s
    currentTimeS = currentWidth / progressControlWidth * (this.data.song.dt / 1000)

    this.setData({
      currentWidth,
      currentTime: moment(currentTimeS * 1000).format('mm:ss')
    })
  },

  // 触摸开始
  handleTouchStart(e) {
    IsProgressControl = !IsProgressControl;
    this.handleProgresCalc(e);
  },
  handleTouchMove(e) {
    this.handleProgresCalc(e);
  },
  // 触摸结束
  handleTouchEnd() {
    // 跳转到对应时间播放
    this.backgroundAudioManager.seek(currentTimeS);
    IsProgressControl = !IsProgressControl
  },

  // 播放顺序的改变
  changePlayOrder() {
    let { playOrder } = this.data;

    if (playOrder == 0) playOrder = 1
    else if (playOrder == 1) playOrder = 2
    else playOrder = 0

    appInstance.globalData.musicPlayOrder = playOrder;
    this.setData({ playOrder })
  },

  // 点击切歌的回调
  handleSwitch(event) {
    // 获取切歌的类型
    let type = event.currentTarget.id;

    // 关闭当前播放的音乐
    this.backgroundAudioManager.stop();

    // 发布消息数据给recommendSong页面
    let publishdata = { type, playOrder: this.data.playOrder }
    this.getPubSubMusic(publishdata);
  },

  // 订阅歌曲的回调【发布状态，订阅得到新的音乐id】
  getPubSubMusic(publishdata) {
    let flag = PubSub.publish('switchType', publishdata)
    // 订阅来自recommendSong页面发布的musicId消息【先订阅后发布】
    PubSub.subscribe('musicId', (msg, musicId) => {
      // 获取音乐详情信息【false下载图片，改变背景颜色】
      this.getMusicInfo(musicId, false);
      // 自动播放当前的音乐
      this.musicControl(true, musicId);
      this.setData({ musicId })

      // 取消订阅
      // 必须取消，因为是订阅的函数还是在pubsubjs里面，不取消，同一事件会订阅多次
      PubSub.unsubscribe('musicId');
    })
    if (!flag) {
      // publish不成功，自动循环该音乐【发布publish成功，返回 true】
      console.log('publish不成功，自动循环该音乐');
      this.musicControl(true, this.data.musicId);
    }
  },

  /**
 * @description 自适应胶囊区:计算导航栏信息
 */
  calcNavBarInfo() {
    // 获取系统信息
    const systemInfo = wx.getSystemInfoSync();
    // 胶囊按钮位置信息
    const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
    console.log(menuButtonInfo);
    this.setData({
      // 导航栏高度 = 状态栏到胶囊的间距（胶囊上坐标位置-状态栏高度） * 2 + 胶囊高度 + 状态栏高度
      navBarHeight: (menuButtonInfo.top - systemInfo.statusBarHeight) * 2 + menuButtonInfo.height + systemInfo.statusBarHeight,
      // 菜单按钮栏(标题栏)的高度
      menuHeight: menuButtonInfo.height,
      menuMarginTop: menuButtonInfo.top,
      menuWidth: menuButtonInfo.width + 10
    })
  },

  // 返回上一个页面
  handleNavigateBack() {
    wx.navigateBack()
  },

  // 判断标题是否滚动
  widthCompare() {
    // 获取元素1和元素2的宽度
    const query = wx.createSelectorQuery();
    query.select('.musicArAl').boundingClientRect()
    query.select('.alName').boundingClientRect()
    query.select('.songContentHeader').boundingClientRect()
    query.select('.progressControl').boundingClientRect()
    query.exec((res) => {
      // 比较两个元素的宽度
      if (res[0].width >= res[1].width) {
        this.setData({ isTitleAnimation: false });
      } else {
        this.setData({ isTitleAnimation: true });
      }
      this.setData({ songContentHeaderHeight: res[2].height - 50 })
      progressControlWidth = res[3].width
    });
  },

  // 判断是否有背景图片的缓存文件，没有就下载为临时文件，最后绘画出来
  async bgcDownload(flag) {
    // 销毁组件后，不在获取
    if (!bgcDownLoadFlag) return;

    // flag =true,读取不下载，就是单曲循环
    let muiscUrl = '';
    if (flag) muiscUrl = wx.getStorageSync('muiscUrl');

    let result = await downloadFile(this.data.song.al.picUrl, muiscUrl, 'muiscUrl')

    const ctx = wx.createCanvasContext('myCanvas')
    ctx.drawImage(result, 0, 0, 100, 100);

    ctx.draw(false, () => {
      wx.canvasGetImageData({
        canvasId: "myCanvas",
        x: 0,
        y: 0,
        width: 100,
        height: 100,
        success: res => {
          let colorThiefArr = colorThief(res.data).palette(20).get()
          let palette = colorThiefArr.find(item => item[0] <= 150 && item[1] <= 150 && item[2] <= 150);
          // console.log(colorThiefArr);
          let paletteDark = palette.map((item) => {
            if (item - 20 <= 0) {
              item = 0
            } else {
              item -= 20
            }
            return item
          })
          this.setData({ palette: [palette, paletteDark] })
        }
      });
    })
  },

  /**
    生命周期函数--监听页面初次渲染完成
  */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    bgcDownLoadFlag = false
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})